package fr.bda.cloud.tray.file;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

import org.apache.commons.io.FileUtils;

import fr.bda.cloud.data.DataDescriptor;
import fr.bda.cloud.storage.StorageUnit;
import fr.bda.cloud.storage.StorageUnitConfiguration;
import fr.bda.cloud.storage.StorageUnitFactory;
import fr.bda.cloud.tray.CloudTray;
import fr.bda.cloud.tray.CloudTrayDialog;
import fr.bda.cloud.tray.CloudTrayDialogController;

public class ReadFileDialogController extends CloudTrayDialogController {

	Dimension dialogDimension = new Dimension(800, 450);
	Dimension dataDescriptorsPanelDimension = new Dimension(350, 300);

	StorageUnitFactory factory = new StorageUnitFactory();

	public ReadFileDialogController(CloudTray cloudTray) {
		super(cloudTray);
		validators.add(new ReadFileDialogValidator(cloudTray));
	}

	@Override
	public <C extends CloudTrayDialogController> void initDialog(CloudTrayDialog<C> dialog) {
		if (ReadFileDialog.class.isInstance(dialog)) {

			final ReadFileDialog readFileDialog = (ReadFileDialog) dialog;
			JPanel formPanel = readFileDialog.getFormPanel();

			// Local directory selector panel
			// -------------------------------
			readFileDialog.pathField = new JTextField(null, 50);
			readFileDialog.browseButton = new JButton("BROWSE...");
			readFileDialog.browseButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					JFileChooser fileChooser = new JFileChooser();
					fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
					fileChooser.showOpenDialog(readFileDialog);
					File selectedDir = fileChooser.getSelectedFile();
					if (selectedDir != null) {
						String path = selectedDir.getAbsolutePath();
						readFileDialog.pathField.setText(path);
					}
				}
			});
			JPanel fileSelectorPanel = new JPanel();
			fileSelectorPanel.add(new JLabel("Local directory: "));
			fileSelectorPanel.add(readFileDialog.pathField);
			fileSelectorPanel.add(readFileDialog.browseButton);
			formPanel.add(fileSelectorPanel, BorderLayout.NORTH);

			// Data descriptor selector panel
			// -------------------------------

			DataDescriptorModelList dataDescriptorSelectorModel = new DataDescriptorModelList();
			Map<String, DataDescriptor> files = new HashMap<>();
			for (StorageUnitConfiguration conf : cloudTray.getData().getStorageUnitConfigurations()) {
				StorageUnit su = factory.initStorageUnit(conf);
				for (DataDescriptor desc : su.listData()) {
					files.put(desc.getFileName(), desc);
				}
			}
			dataDescriptorSelectorModel.addStorageUnitConfigurations(files.values());
			readFileDialog.dataDescriptors = new JList<DataDescriptor>(dataDescriptorSelectorModel);
			readFileDialog.dataDescriptors.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
			readFileDialog.dataDescriptors.setLayoutOrientation(JList.VERTICAL_WRAP);
			readFileDialog.dataDescriptors.setPreferredSize(dataDescriptorsPanelDimension);
			formPanel.add(readFileDialog.dataDescriptors, BorderLayout.SOUTH);

			dialog.setSize(dialogDimension);
		}
	}

	@Override
	public <C extends CloudTrayDialogController> void saveDialogData(CloudTrayDialog<C> dialog) {
		if (ReadFileDialog.class.isInstance(dialog)) {

			final ReadFileDialog readFileDialog = (ReadFileDialog) dialog;

			File downloadDir = new File(readFileDialog.pathField.getText());

			for (int i : readFileDialog.dataDescriptors.getSelectedIndices()) {
				DataDescriptor desc = readFileDialog.dataDescriptors.getModel().getElementAt(i);

				switch (desc.getStorageMode()) {
				case RAID_1:

					StorageUnitConfiguration suConf = desc.getStorageUnits().get(0);
					byte[] data = factory.initStorageUnit(suConf).readData(desc);
					try {
						FileUtils.writeByteArrayToFile(new File(downloadDir, desc.getFileName()), data);
					} catch (IOException e) {
						e.printStackTrace();
					}

					break;

				default:
					System.err.println("Storage mode [" + desc.getStorageMode().name() + "] not managed");
					break;
				}
			}
		}

	}

}
